package welsir.security.aop;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import welsir.entity.dos.User;
import welsir.entity.dos.UserRole;
import welsir.entity.enums.ResultCode;
import welsir.exception.ServiceException;
import welsir.mapper.UserMapper;
import welsir.mapper.UserRoleMapper;
import welsir.security.AuthUser;
import welsir.security.annotations.Authentication;
import welsir.security.enums.UserEnums;
import welsir.util.ResultUtil;
import welsir.util.RoleAuthUtil;
import welsir.util.TokenUtil;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;

/**
 * @author welsir
 * @date 2023/3/7 22:56
 */
@Aspect
@Component
@Slf4j
public class AuthenticationAspect {

    @Resource
    private TokenUtil tokenUtil;
    @Resource
    private UserMapper userMapper;
    @Resource
    private UserRoleMapper userRoleMapper;
    @Resource
    private RoleAuthUtil roleAuthUtil;

    @Pointcut(value = "@annotation(welsir.security.annotations.Authentication)")
    public void pointcut() {}

    @AfterReturning(returning = "result", value = "@annotation(welsir.security.annotations.Authentication)")
    public void after(JoinPoint joinPoint, Object result){
        log.info("refreshing token");
        Object[] args = joinPoint.getArgs();
        for (Object arg : args) {
            if (arg instanceof HttpServletRequest) {
                HttpServletRequest request = (HttpServletRequest) arg;
                String token = request.getParameter("token");
                if (token != null) {
                    //通过token获name值更新token有效期
                    AuthUser authUser = tokenUtil.parseToken(token);
                    if(authUser==null){
                        throw new ServiceException(ResultCode.USER_NOT_EXIST);
                    }
                    tokenUtil.refreshToken(token);
                    log.info("refreshed token");
                }else{
                    log.info("not refreshed token");
                }
            }
        }
    }
    @Around("pointcut() && @annotation(authentication)")
    public Object interceptor(ProceedingJoinPoint proceedingJoinPoint, Authentication authentication){
        UserEnums role = authentication.role();

        if(role!=UserEnums.USER){
            //获取token
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder
                    .getRequestAttributes()).getRequest();
            String token = request.getHeader("token");
            AuthUser authUser = tokenUtil.parseToken(token);
            //判断用户身份 2为用户 3为管理员
            boolean b = roleAuthUtil.isAuth(authUser.getId(), role);
            if(b){
                //true
                try {
                    return proceedingJoinPoint.proceed();
                } catch (Throwable e) {
                    return ResultUtil.error(ResultCode.ERROR);
                }
            }
        }else {
            try {
                return proceedingJoinPoint.proceed();
            } catch (Throwable e) {
                return ResultUtil.error(ResultCode.ERROR);
            }
        }
        return null;
    }
}
